package czolgisci;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

import utils.delegate.BadArgumentsException;
import utils.delegate.MethodDelegate;
import utils.input.KeyboardListener;
import utils.time.Clock;
import czolgisci.display.DisplayManager;
import czolgisci.display.GraphicInterface;
import czolgisci.map.MapManager;

/**
 * Główna klasa gry - silnik. Zarządza grą, inicjuje wszystkie potrzebne
 * obiekty, wywołuje je w odpowiednim momencie.
 * 
 * obiekt tej klasa agreguje obiekty klas:
 * <ul>
 * <li>Engine (singleton) </li>
 * <li>LifeManager</li>
 * <li>KeyboardListener</li>
 * <li>MapManager</li>
 * <li>Clock</li>
 * </ul>
 * oraz asocjuje obiekt klasy GraphicInterface
 * 
 * @pattern
 * <ul>
 * <li>Singleton -ponieważ można stworzyć tylko jedną grę w czasie działania
 * programu</li>
 * <li>Fasada - udostępnia metody wysokiego poziomu do zarządzające grą, np.:
 * start, pause, resume</li>
 * </ul>
 * 
 * @author kasztan
 * @version 0.5
 */
public class Engine
{
	private DisplayManager displayManager;

	/**
	 * metoda wzorca Singleton
	 * 
	 * @return jedyna instancja klasy
	 */
	static public Engine getInstance()
	{
		instance = new Engine();
		return instance;
	}

	/**
	 * metoda wzorca Fasada, klasa Engine zarządza zakończeniem całej gry
	 */
	public void destroy()
	{

	}

	/**
	 * metoda wzorca Fasada, inicjalizuję klasę Engine i wszystkie inne
	 * niezbędne do funkcjonowania gry
	 * 
	 * @param root
	 *            instancja menedżera okienek
	 * @param obszar
	 *            na którym można rysować grę
	 * @param tablica
	 *            zawierająca nazwy graczy (np. Bolek, Lolek)
	 */
	public void init(GraphicInterface root, Graphics2D drawingArea,
			String playerNamesArr[])
	{
		this.drawingArea = drawingArea;
		rootFrame = root;
		interval = new Clock();

		keyListener = new KeyboardListener(root);
		registerKeys();
		
		interval.addListener(keyListener);
		/*
		 * tilesManager = new MapManager(new Map(10, 10, new char[10][10]), new
		 * StandardTileFactory()); displayManager =
		 * DisplayManager.getInstance();
		 * displayManager.init(tilesManager.iterator(), drawingArea);
		 * 
		 * attachImages();
		 * 
		 */
		attachImages();
		initializePlayers(playerNamesArr);
		interval.start();
	}

	/**
	 * metoda wywoływana po zniszczeniu czołgu, usuwa jedno życie jednego
	 * gracza; jeśli gracz już nie ma żyć gra jest kończona
	 * 
	 * @param name
	 *            nazwa gracza, którego czołg został zniszczony
	 */
	public void onTankDestroy(String playerName)
	{
		if (playerLifesManager.removeLife(playerName) == 0)
		{ // jesli graczowi zostało zero żyć kończymy grę
			end();
		}
	}

	/**
	 * koniec gry, wyświetlenie wyniku
	 */
	public void end()
	{
		interval.stop();
		rootFrame.endGame(playerLifesManager.getWinnerName());
	}

	/**
	 * zatrzymanie gry, pauza
	 */
	public void pause()
	{
	
	}

	/**
	 * odświeżenie gry
	 */
	public void refresh()
	{

	}

	/**
	 * przywrócenie gry po pauzie
	 */
	public void resume()
	{

	}

	/**
	 * rozpoczęcie gry
	 */
	public void start()
	{

	}
	
	private Graphics2D drawingArea;

	private static Engine instance;

	private GraphicInterface rootFrame;

	private Players playerLifesManager;

	private KeyboardListener keyListener;

	private MapManager tilesManager;

	private Clock interval;

	private Engine()
	{

	}
	private void initializePlayers(String[] playerNamesArr) 
	{
		playerLifesManager = new Players();
		for (String name : playerNamesArr)
		{
			System.out.println("Dodaje gracza: " + name);
			playerLifesManager.add(name);
			try
			{
				rootFrame.createLifeField(name, playerLifesManager.getLifes(name));
			} catch (IllegalArgumentException e)
			{
				e.printStackTrace();
			}
		}
	}
	private void attachImages()
	{
		BufferedImage bimg = null;
        try {
            bimg = ImageIO.read(new File("/home/kasztan/eclipse-projects/czolgisci/bin/biegnaca_kura.jpg"));
        } catch (Exception e) {   
            e.printStackTrace();   
        }
        drawingArea.drawImage(bimg, null, 0, 0);
	}

	private void registerKeys()
	{
		MethodDelegate method, method2;
		try
		{
			method = new MethodDelegate(
					System.out,
					System.out.getClass()
						.getMethod("println", new Class[] { String.class }), 
				new Object[] { "q key pressed" });
			keyListener.registerKey('q', method);
			method2 = new MethodDelegate(
					System.out,
					System.out.getClass()
						.getMethod("println", new Class[] { String.class }), 
				new Object[] { "r key pressed" });
			keyListener.registerKey('r', method2);
		} catch (BadArgumentsException e)
		{
			e.printStackTrace();
		} catch (SecurityException e)
		{
			e.printStackTrace();
		} catch (NoSuchMethodException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
